package com.eddy.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.eddy.entity.DataDecrypt;
import com.eddy.entity.DataEncrypt;
import com.eddy.entity.SecretKey;
import org.apache.log4j.Logger;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.Random;

public class DataEncryptUtils {
    private static Logger log = Logger.getLogger(DataEncryptUtils.class);

    private static final String KEY_SHA = "SHA";
    /**
     * 加密响应
     * @param data 返回数据
     * @param flag 执行结果
     * @return 加密对象
     */
    public static String encryptData(Object data,String flag){
        DataEncrypt encrypt = new DataEncrypt();
        encrypt.setFlag(flag);
        try {
            // 生成aes秘钥
            String encryptKey = DataEncryptUtils.getRandomString(16);
            // 使用公钥加密Key
            encrypt.setEncrypt(RSAUtils.encryptedDataOnJava(encryptKey, SecretKey.secretKey.getEncryptKey()));
            // 使用Key加密数据
            String encryptData = JSONObject.toJSONString(data);
            encrypt.setData(AesEncryptUtils.encrypt(encryptData, encryptKey));
        }catch (Exception e){
            log.error("EncryptData Exception:",e);
        }
        return JSON.toJSONString(encrypt);
    }

    public static String encryptData(String data,String flag){
        DataEncrypt encrypt = new DataEncrypt();
        encrypt.setFlag(flag);
        try {
            // 生成aes秘钥
            String encryptKey = DataEncryptUtils.getRandomString(16);
            // 使用公钥加密Key
            encrypt.setEncrypt(RSAUtils.encryptedDataOnJava(encryptKey, SecretKey.secretKey.getEncryptKey()));
            // 使用Key加密数据
            encrypt.setData(AesEncryptUtils.encrypt(data, encryptKey));
        }catch (Exception e){
            log.error("EncryptData Exception:",e);
        }
        return JSON.toJSONString(encrypt);
    }

    /**
     * 解密请求
     * @param decrypt 请求对象
     * @return String 请求
     */
    public static String decryptParameter(DataDecrypt decrypt){
        try {
            //使用私钥解密Key
            String decryptKey = RSAUtils.decryptDataOnJava(decrypt.getDecrypt(), SecretKey.secretKey.getDecryptKey());
            //使用Key解密请求
            return AesEncryptUtils.decrypt(decrypt.getParameter(),decryptKey);
        }catch (Exception e){
            log.error("DecryptParameter Exception:",e);
        }
        return "";
    }

    /**
     * 解密请求
     * @param decrypt 请求对象
     * @param clazz 类
     * @param <T>
     * @return <T> 请求
     */
    public static <T> T decryptParameter(DataDecrypt decrypt,Class<T> clazz){
        try {
            //使用私钥解密Key
            String decryptKey = RSAUtils.decryptDataOnJava(decrypt.getDecrypt(), SecretKey.secretKey.getDecryptKey());
            //System.out.println("解密后的密匙："+decryptKey);
            //使用Key解密请求
            String parameter = AesEncryptUtils.decrypt(decrypt.getParameter(), decryptKey);
            //System.out.println("解密后的数据："+parameter);
            //将字符串转为对象
            return JSONObject.parseObject(parameter, clazz);
        }catch (Exception e){
            log.error("DecryptParameter Exception:",e);
        }
        return JSONObject.parseObject(null, clazz);
    }

    /**
     * 创建指定位数的随机字符串
     * @param length 表示生成字符串的长度
     * @return 字符串
     */
    public static String getRandomString(int length) {
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

    /**
     * SHA加密（密码）
     * @param data 数据
     * @return
     */
    public static String shaEncrypt(String data){
        BigInteger sha = null;
        byte[] inputData = data.getBytes();
        try {
            MessageDigest messageDigest = MessageDigest.getInstance(KEY_SHA);
            messageDigest.update(inputData);
            sha = new BigInteger(messageDigest.digest());
            return sha.toString(32);
        } catch (Exception e) {
            log.error("Sha Encrypt Exception",e);
            return null;
        }
    }
}
